package com.qf.fmall2202.index.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.fmall2202.index.entity.Category;
import com.qf.fmall2202.index.mapper.CategoryMapper;
import com.qf.fmall2202.index.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall2202.product.entity.Product;
import com.qf.fmall2202.product.entity.ProductImg;
import com.qf.fmall2202.product.service.IProductImgService;
import com.qf.fmall2202.product.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author dong_
 * @since 2022-11-07
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    IProductService productService;

    @Autowired
    IProductImgService productImgService;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryList() {

        //1. 查询出所有商品分类 信息
        final List<Category> allCategories = this.list();

        //2. 组织 商品分类信息 为层级结构
        List<Category> topLevelCategory = organiezCategory(0,allCategories);

        return topLevelCategory;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Category> categoryRecommends() {

        //1. 查询顶级分类信息
        final List<Category> topCategorieList = this.list(new QueryWrapper<Category>().eq("parent_id", 0));

        //2. 查询各顶级分类下的商品信息
        topCategorieList.forEach(category -> {

            // 查询该分类下的商品按照销量排名的前六名
            final Page<Product> productPage = new Page<>(1, 6);
            productPage.addOrder(OrderItem.desc("sold_num"));
            final LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<Product>()
                    .eq(Product::getRootCategoryId, category.getCategoryId());
            productService.page(productPage, queryWrapper);


            // 把查询到的商品信息挂载到 category 对象上
            final List<Product> productList = productPage.getRecords();

            // 判断如果当前顶级分类下真的有商品时，再遍历商品信息填充图片 信息
            if (productList!=null && productList.size()>0){
                // 把商品的图片信息查出来
                // 查询这三个商品对应所有图片信息
                final QueryWrapper<ProductImg> productImgQueryWrapper = new QueryWrapper<>();

                // List<Product> --> List<ProductID>
                final List<String> productIdList = productList.stream().map(Product::getProductId).collect(Collectors.toList());

                productImgQueryWrapper.in("item_id",productIdList);

                final List<ProductImg> productImgsList = productImgService.list(productImgQueryWrapper);


                // 分组 List<ProductImg>  ---> Map<商品ID， List<商品图片> >
                final Map<String, List<ProductImg>> productImgMap = productImgsList.stream()
                        .collect(Collectors.groupingBy(ProductImg::getItemId));

                // 填充 productList

                productList.forEach(product -> {

                    List<ProductImg> productImgs = productImgMap.get(product.getProductId());
                    if (productImgs==null){
                        productImgs = new ArrayList<>();
                    }
                    product.setImgs(productImgs);

                });
            }

            category.setProducts(productList);

        });

        return topCategorieList;
    }

    /**
     * 按照给定的 parentid组织 分类信息的层级结构
     * @param parentId
     * @param allCategories
     * @return
     */
    private List<Category> organiezCategory(int parentId, List<Category> allCategories) {

        //0. 按照 parentId 对 allCategories 进行分组，处理成map结构

        final Map<Integer, List<Category>> parentIdMap = allCategories.stream()
                .collect(Collectors.groupingBy(Category::getParentId));


        //1. 查询出所有顶级 分类信息，得到 List<顶级分类>
//        final List<Category> topCategoryList = allCategories
//                .stream()
//                .filter(category -> category.getParentId().equals(parentId))
//                .collect(Collectors.toList());
        final List<Category> topCategoryList = parentIdMap.get(parentId);


        //2. 遍历 List<顶级分类> ，为每一个 顶级分类信息 查找下级分类信息 List<下级分类>，并挂载
        populateChildCategory(topCategoryList,parentIdMap);

        return topCategoryList;
    }


    private void populateChildCategory(List<Category> parentCategory, Map<Integer, List<Category>> parentIdMap) {

        parentCategory.forEach(category -> {

            // 寻找当前分类 的下级分类
            final List<Category> childCategories = parentIdMap.get(category.getCategoryId());


            if (childCategories!=null && childCategories.size()>0) {
                populateChildCategory(childCategories,parentIdMap);
            }

            // 把下级分类信息挂载
            category.setCategories(childCategories);

        });


    }

    /**
     * 为 父分类填充子分类信息
     * @param parentCategory
     * @param allCategories
     */
    private void populateChildCategory(List<Category> parentCategory, List<Category> allCategories) {
        //1. 遍历 parentCategory ，为每一个 分类信息 查找 子分类信息，并挂载
        parentCategory.forEach(category -> {

            final Integer currentId = category.getCategoryId();

            // 查找子分类信息
            final List<Category> childCategoryList = allCategories.stream()
                    .filter(c -> c.getParentId().equals(currentId))
                    .collect(Collectors.toList());

            if ( childCategoryList.size()>0 ){
                populateChildCategory(childCategoryList,allCategories);
            }

            // 挂载
            category.setCategories(childCategoryList);
        });


    }
}
